import { ECPairFactory } from 'ecpair';
import * as tinysecp from 'tiny-secp256k1';
import crypto from 'crypto';
import { binaryToBase58 } from './base58.js';
import r from "jsrsasign";

const bob = crypto.createECDH('secp256k1');
bob.generateKeys();
const ECPair = ECPairFactory(tinysecp);
const keyPair = ECPair.fromPrivateKey(bob.getPrivateKey(), { compressed: true });
const pubKey = keyPair.publicKey;
const privateKey = keyPair.privateKey;
const pubKeyHash = getPublicKeyHash(pubKey);
console.log("privateKey:", Buffer.from(privateKey).toString('hex'));
console.log("publicKey:", Buffer.from(pubKey).toString('hex'), "length:", pubKey.length);
console.log("publicKeyHash:", pubKeyHash.toString('hex'));
console.log('address:', getAddress(pubKeyHash));

const prvhex = bob.getPrivateKey().toString('hex');
const pubhex = bob.getPublicKey().toString('hex');
const keyPair1 = ECPair.fromPrivateKey(bob.getPrivateKey());
const privhex1 = keyPair1.privateKey.toString('hex');
console.log("prvhex:", prvhex, "prvhex1:", privhex1);
const key = "42946e14cd837a75df282394ffefe17618d06e98d026446f0906b88fd331be5c:0";
const sig = new r.Signature({ alg: "SHA256withECDSA" });
sig.init({ d: prvhex, curve: 'secp256k1' });
sig.updateString(key);
const sigValueHex = sig.sign();
console.log("key:", key, "sign:", sigValueHex);

const sig2 = new r.Signature({ "alg": 'SHA256withECDSA'  });
sig2.init({ xy: pubhex, curve: 'secp256k1'  });
sig2.updateString(key);
const result = sig2.verify(sigValueHex);
console.log("verify result:", result);

function getPublicKeyHash(pubKey) {
  const sha256 = crypto.createHash('sha256');
  const hash256Binary = sha256.update(pubKey).digest();
  const ripemd160 = crypto.createHash('ripemd160');
  // get the public key in a compressed format 20 bytes
  const pubKeyHash = ripemd160.update(hash256Binary).digest();
  return pubKeyHash;
}

function getAddress(pubKeyHash) {
  const leaderBuffer = Buffer.from([0]);
  const hashBuffer = Buffer.from(pubKeyHash);

  const payloadBuffer = Buffer.concat([leaderBuffer, hashBuffer]);
  const checkSumBuffer = Buffer.from(checksum(payloadBuffer));
  const addressBuffer = Buffer.concat([leaderBuffer, hashBuffer, checkSumBuffer]);
  return binaryToBase58(addressBuffer);
}

function doubleHash(data) {
  const sha256 = crypto.createHash('sha256');
  const data1 = sha256.update(data).digest();
  const sha256Again = crypto.createHash('sha256');
  return sha256Again.update(data1).digest();
}

function checksum(data) {
  const doubleHashData = doubleHash(data);
  return doubleHashData.subarray(0, 4);
}
